/**
 * 浅拷贝
 */
let obj = {
  name: 'xiaoming',
  age: 29,
  hobbys: ['sport', 'shopping']
}

// 1. 直接赋值
let objCp1 = obj

/**
 * 深拷贝
 */
// 1. ... 只能深拷贝单层，！！如果对象属性也是object，则只能浅拷贝
// let objCp2 = {...obj}
// objCp2.hobbys[0] = 'running'
// console.log(obj)
// console.log(objCp2)

// 2. Object.assign ！！同样不能深拷贝属性为Object的对象
// let objCp3 = Object.assign({}, obj)
// objCp3.hobbys[0] = 'walking'
// console.log(obj)

function deepClone(obj) {
  if (typeof obj !== 'object' || obj == null) {
    return obj
  }

  if (obj instanceof RegExp) {
    return new RegExp(obj)
  }

  if (obj instanceof Date) {
    return new Date(obj)
  }

  let newObj = new obj.constructor() // 继承源对象的类

  for (const key in obj) {
    if (obj.hasOwnProperty(key)) { // for in 会遍历原型链上的属性
      const element = obj[key];
      if (typeof element === 'object') {
        newObj[key] = deepClone(element)
      } else {
        newObj[key] = element
      }
    }
  }

  return newObj
}

let objCp4 = deepClone(obj)
objCp4.hobbys[0] = 'tennis'
console.log(obj);